package grpc

import (
	"context"
	"google.golang.org/grpc"
	"google.golang.org/protobuf/types/known/timestamppb"
	commentv1 "jk-time/webook/api/proto/gen/comment/v1"
	"jk-time/webook/comment/domain"
	"jk-time/webook/comment/service"
	"math"
)

type CommentServiceServer struct {
	commentv1.UnimplementedCommentSerivceServer
	svc service.CommentService
}

func NewCommentServiceServer(svc service.CommentService) *CommentServiceServer {
	return &CommentServiceServer{svc: svc}
}

func (w *CommentServiceServer) Register(server *grpc.Server) {
	commentv1.RegisterCommentSerivceServer(server, w)
}
func (w *CommentServiceServer) GetCommentList(ctx context.Context, in *commentv1.CommentListRequest) (*commentv1.CommentListResponse, error) {
	if in.MinId <= 0 {
		in.MinId = math.MaxInt64
	}
	if in.Limit <= 0 {
		in.Limit = 100
	}
	res, err := w.svc.GetCommentList(ctx, in.Biz, in.BizId, in.MinId, in.Limit)
	if err != nil {
		return &commentv1.CommentListResponse{}, err
	}
	return &commentv1.CommentListResponse{
		Comments: w.toDTO(res),
	}, nil
}
func (w *CommentServiceServer) DeleteComment(ctx context.Context, in *commentv1.DeleteCommentRequest) (*commentv1.DeleteCommentResponse, error) {
	err := w.svc.DeleteComment(ctx, in.Id)
	return &commentv1.DeleteCommentResponse{}, err
}
func (w *CommentServiceServer) CreateComment(ctx context.Context, in *commentv1.CreateCommentRequest) (*commentv1.CreateCommentResponse, error) {
	err := w.svc.CreateComment(ctx, w.toDomain(in.GetComment()))
	return &commentv1.CreateCommentResponse{}, err
}
func (w *CommentServiceServer) GetMoreReplies(ctx context.Context,
	in *commentv1.GetMoreRepliesRequest) (*commentv1.GetMoreRepliesResponse, error) {
	res, err := w.svc.GetMoreReplies(ctx, in.GetRid(), in.GetMaxId(), in.GetLimit())
	if err != nil {
		return &commentv1.GetMoreRepliesResponse{}, err
	}
	return &commentv1.GetMoreRepliesResponse{
		Replies: w.toDTO(res),
	}, nil
}
func (w *CommentServiceServer) toDTO(comment []domain.Comment) []*commentv1.Comment {
	res := make([]*commentv1.Comment, len(comment))
	for i, c := range comment {
		comment := &commentv1.Comment{
			Id:      c.Id,
			Uid:     c.Commentator.ID,
			Bizid:   c.BizId,
			Biz:     c.Biz,
			Content: c.Content,
			Ctime:   timestamppb.New(c.CTime),
		}
		if c.RootComment != nil {
			comment.RootComment = &commentv1.Comment{
				Id: c.RootComment.Id,
			}
		}
		if c.ParentComment != nil {
			comment.ParentComment = &commentv1.Comment{
				Id: c.ParentComment.Id,
			}
		}
		res[i] = comment
	}
	return res
}
func (w *CommentServiceServer) toDomain(comment *commentv1.Comment) domain.Comment {
	domainComment := domain.Comment{
		Id:      comment.Id,
		Biz:     comment.Biz,
		BizId:   comment.Bizid,
		Content: comment.Content,
		Commentator: domain.User{
			ID: comment.Uid,
		},
	}
	if comment.GetParentComment() != nil {
		domainComment.ParentComment = &domain.Comment{
			Id: comment.GetParentComment().GetId(),
		}
	}
	if comment.GetRootComment() != nil {
		domainComment.RootComment = &domain.Comment{
			Id: comment.GetRootComment().GetId(),
		}
	}
	return domainComment
}
